package org.aalku.adbcopy;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

final class StreamReaderThread extends Thread {
	private final InputStream in;
	private ByteArrayOutputStream mainOutBuffer;
	private boolean eof = false;

	StreamReaderThread(InputStream in) {
		this.in = in;
		this.mainOutBuffer = new ByteArrayOutputStream();
	}

	public void run() {
		int b;
		try {
			while ((b = in.read()) >= 0) {
				synchronized (mainOutBuffer) {
					//debug(b);
					mainOutBuffer.write(b);
				}
			}
			synchronized (mainOutBuffer) {
				eof = true;
			}
		} catch (IOException e) {
			throw new RuntimeException("Stream error", e);
		}
	}

	@SuppressWarnings("unused")
	private void debug(int b) {
		String c;
		if (b == '\r') {
			c = "\\r";
		} else if (b == '\n') {
			c = "\\n";
		} else {
			c = String.format("0x%02x", b & 0xFF);
		}
		System.err.println("<! " + c);
	}

	public List<String> getOutputLines() {
		List<String> res = new ArrayList<String>();
		ByteArrayOutputStream line = new ByteArrayOutputStream();
		byte[] array;
		synchronized (mainOutBuffer) {
			array = mainOutBuffer.toByteArray();
			for (int i = 0; i < array.length; i++) {
				byte b = array[i];
				//System.err.println("<! " + String.format("0x%02x", b & 0xFF));
				if (b == '\r') {
					//System.err.println("<!skip");
				} else {
					if (b == '\n') {
						//System.err.println("<!break");
						String s = line.toString();
//						System.err.println("<< " + s);
						res.add(s);
						line.reset();
					} else {
						line.write(b);
					}
				}
			}
			mainOutBuffer.reset();
			if (eof) {
				String s = line.toString();
//				System.err.println("<< " + s);
				res.add(s);
			} else {
				try {
					line.writeTo(mainOutBuffer);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}
		return res;
	}

	public boolean anyOutput() {
		synchronized (mainOutBuffer) {
			return mainOutBuffer.size() > 0;
		}
	}
}